package com.atguigu.crowd.handler;

import com.atguigu.crowd.api.MySQLRemoteService;
import com.atguigu.crowd.api.RedisRemoteService;
import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.po.MemberPO;
import com.atguigu.crowd.entity.vo.MemberLoginVo;
import com.atguigu.crowd.entity.vo.MemberVo;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author zwj
 * @create 2021-08-09-10:37
 */
@Controller
public class MemberHandler {

    @Autowired
    private RedisRemoteService redisRemoteService;

    @Autowired
    private MySQLRemoteService mySQLRemoteService;

    @RequestMapping("/auth/menber/do/logout")
    public String logout(HttpSession session){
        session.invalidate();
        return "redirect:/";
    }

    @RequestMapping("/auth/member/do/login")
    public String login(@RequestParam("loginacct") String loginacct, @RequestParam("uiserpswd") String uiserpswd,
                        ModelMap modelMap, HttpSession session){
        ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if (ResultEntity.FAILED.equals(resultEntity.getResult())){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,resultEntity.getMessage());
            return "member-login";
        }
        MemberPO memberPO = resultEntity.getData();
        if (memberPO == null){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        String dataBasePswd = memberPO.getUserpswd();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bCryptPasswordEncoder.matches(uiserpswd,dataBasePswd)){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        MemberLoginVo memberLoginVo = new MemberLoginVo(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER,memberLoginVo);
        return "redirect:http://121.196.205.151/auth/member/to/center/page";
    }

    @RequestMapping("/auth/do/member/register")
    public String register(MemberVo memberVo, ModelMap modelMap){
        // 1.获取用户输入的手机号
        String phoneNum = memberVo.getPhoneNum();
        // 2.拼接Redis中存储的Key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        // 3.从Redis读取Key对应的value
        ResultEntity<String> redisValue = redisRemoteService.getRedisStringValueByKeyRemote(key);
        // 4.检查查询操作是否有效
        String result = redisValue.getResult();
        if (ResultEntity.FAILED.equals(result)){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,redisValue.getMessage());
            return "member-reg";
        }

        String redisCode = redisValue.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
            return "member-reg";
        }
        // 5.能从Redis查询到，则比较两者是否一致
        String formCode = memberVo.getCode();
        if (!Objects.equals(formCode,redisCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
        // 6.一致，将value从Redis中删除,这里失败就涉及到分布式事务了
        redisRemoteService.removeRedisKeyRemote(key);
        // 7.执行密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        memberVo.setUserpswd(passwordEncoder.encode(memberVo.getUserpswd()));
        // 8. 执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVo,memberPO);
        ResultEntity<String> saveResultEntity = mySQLRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(saveResultEntity.getResult())){
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());
            return "member-reg";
        }
        return "redirect:http://121.196.205.151/auth/member/to/login/page";
    }

    @ResponseBody
    @RequestMapping(value = "/auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam(value = "phoneNum") String phoneNum) {
        // 3.如果成功，则将验证码存入Redis
        String code = "0901";
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key,code,3,TimeUnit.MINUTES);

        // 4. 判断是否成功存入 Redis
        if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
            return ResultEntity.successWithoutData();
        }else {
            return saveCodeResultEntity;
        }
    }

}
